const setVal = (val, el, vNode) => {
  if (vNode.componentInstance) {
    vNode.componentInstance.$emit('input', val)
  } else {
    el.value = val
    el.dispatchEvent(new Event('input'))
  }
}

const install = Vue => {
  Vue.directive('maxNumber', {
    inserted (el, bind, vNode) {
      el.addEventListener('keyup', event => {
        const e = event || window.event
        let content = parseFloat(e.target.value)
        if (Number.isNaN(content)) {
          content = 0
        }
        setVal(Math.min(bind.value, content), el, vNode)
      })
    }
  })
  Vue.directive('minNumber', {
    inserted (el, bind, vNode) {
      el.addEventListener('keyup', event => {
        const e = event || window.event
        let content = parseFloat(e.target.value)
        if (Number.isNaN(content)) {
          content = 0
        }
        setVal(Math.max(bind.value, content), el, vNode)
      })
    }
  })

  Vue.directive('preventReClick', {
    inserted: function (el, binding, vnode) { // 每当指令绑定到元素上的时候，会立即执行这个bind函数，只执行一次
      function clickHandler (e) {
        if (el.disabled) {
          e.preventDefault()
          e.stopPropagation()
          return false
        }
        if (!el.disabled) {
          el.disabled = true
          setTimeout(() => {
            el.disabled = false
          }, binding.value || 3000)
        }
      }

      // 给当前元素绑定个私有变量，方便在unbind中可以解除事件监听
      el.__vueClickOutside__ = clickHandler
      el.addEventListener('click', clickHandler)
    },
    unbind (el, binding) {
      // 解除事件监听
      el.removeEventListener('click', el.__vueClickOutside__)
      delete el.__vueClickOutside__
    }
  })

  Vue.directive('saveImage', {
    inserted (el, binding) {
      let tapTime = 500
      let tapTimer = ''
      let actionSheetInstance = null
      let downloadUrl = ''

      function downLoad () {
        console.log('onSelect', downloadUrl)
        if (window.android && window.android.downloadFile) {
          window.android.downloadFile(downloadUrl, `新闻图片${Date.now()}.png`)
        }
      }

      function doSave (src) {
        downloadUrl = src
        tapTimer = setTimeout(() => {
          console.log('setTimeout')
          clearTimeout(tapTimer)
          tapTimer = null
          if (binding.value) {
            return binding.value(src)
          }
          actionSheetInstance = new Vue().$createActionSheet({
            title: '',
            active: 0,
            data: [
              {
                content: '保存图片'
              }
            ],
            onSelect: (item, index) => {
              downLoad()
            }
          })
          actionSheetInstance.show()
        }, tapTime)
      }

      function startDoSave (e) {
        let target = e.target
        if (target.tagName.toUpperCase() === 'IMG') {
          doSave(target.src)
        }
      }

      el.addEventListener('touchstart', e => {
        console.time('tap')
        console.log('touchstart')
        startDoSave(e)
      }, true)
      el.addEventListener('mousedown', e => {
        startDoSave(e)
      })
      el.addEventListener('touchend', e => {
        console.timeEnd('tap')
        console.log('touchend')
        if (tapTimer) {
          clearTimeout(tapTimer)
        } else if (e.target.tagName.toUpperCase() === 'IMG') {
          e.preventDefault()
          e.stopPropagation()
        }
      })
      el.addEventListener('touchmove', e => {
        clearTimeout(tapTimer)
      })
      el.addEventListener('mouseup', e => {
        if (tapTimer) {
          clearTimeout(tapTimer)
        } else if (e.target.tagName.toUpperCase() === 'IMG') {
          e.preventDefault()
          e.stopPropagation()
        }
      })
    }
  })
  Vue.directive('align', {
    inserted(el, binding) {
      let style = window.getComputedStyle(el)
      let lineHeight = parseInt(style['lineHeight'])
      let height = el.offsetHeight
      if (height >= 2 * lineHeight) {
        el.className += ' ' + binding.value
      }
    }
  })

  Vue.component('write', {
      render(createElement) {
        return createElement(
          'h1',
          this.$slots.default // 子节点数组
          ,
          {
            props: {
              title: {
                type: String
              }
            },
            directives: [
              {
                name: 'model',
                value: '2'
              }
            ]
          }
        )
      },
    }
  )
  Vue.directive('remainScroll', {
      inserted(el, binding, vnode) {
        el.addEventListener('scroll', e => {
          let scrollTop = e.target.scrollTop
          sessionStorage.setItem(binding.value, scrollTop)
        })
        vnode.context.$on('hook:activated', function () {
          let scrollTop = sessionStorage.getItem(binding.value) || 0
          el.scrollTop = scrollTop
        })
      },
      componentUpdated(el, binding){
        let scrollTop = sessionStorage.getItem(binding.value) || 0
        el.scrollTop = scrollTop
      }
    }
  )
  /*还原cube-ui 滚动*/
  Vue.directive('remainScrollCube', {
      bind(el, binding, vnode) {
        el._isScroll = false
        vnode.componentInstance.$on('before-scroll-start', function (arg) {
          el._isScroll = true
        })
        vnode.componentInstance.$on('scroll-end', function (arg) {
          el._isScroll = false
          vnode.context.$sessionStorage.set(binding.value, arg)
        })
        vnode.context.$on('hook:activated', function () {
          vnode.context.$nextTick(()=>{
            rollback(binding, vnode)
          })
        })
        vnode.context.$on('hook:created', function () {
          console.log('hook:created', this.$route.name)
          vnode.context.$nextTick(()=>{
            rollback(binding, vnode)
          })
        })
        /*vnode.context.$on('hook:beforeDestroy', function () {
          if(!vnode.context.$route.meta.keepAlive) {
            vnode.context.$sessionStorage.remove(binding.value)
          }
        })*/
      }
    }
  )
}

/*betterScroll rollback*/
function rollback (binding, vnode) {
  // console.log('rollback')
  if (!vnode.componentInstance) {
    return
  }
  vnode.componentInstance.forceUpdate(true, false)
  let {x=0, y=0} = vnode.context.$sessionStorage.get(binding.value) || {}
  vnode.componentInstance.scroll && vnode.componentInstance.scroll.scrollTo(x, y)
}

export default install
